package com.finance.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.finance.entity.TicketOrderByScreeningDate;
import com.finance.mapper.TicketOrderByScreeningDateMapper;
import com.finance.service.TicketOrderByScreeningDateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * C20
 * 影票订单数据(放映日期)Service实现类
 */
@Slf4j
@Service
public class TicketOrderByScreeningDateServiceImpl extends ServiceImpl<TicketOrderByScreeningDateMapper, TicketOrderByScreeningDate> implements TicketOrderByScreeningDateService {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int processOrders(List<Map<String, String>> records) {
        return processOrders(records, null, false, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int processOrders(List<Map<String, String>> records, String searchDate, boolean forceUpdate, String cinemaId) {
        if (records == null || records.isEmpty()) {
            log.warn("No records to process for C20 data");
            return 0;
        }

        // 如果强制更新，先删除指定日期和影院ID的数据
        if (forceUpdate) {
            LambdaQueryWrapper<TicketOrderByScreeningDate> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TicketOrderByScreeningDate::getSearchDate, searchDate)
                  .eq(TicketOrderByScreeningDate::getCinemaId, cinemaId);
            this.remove(wrapper);
        } else if (searchDate != null) {
            // 如果不是强制更新，先检查数据是否存在
            long count = lambdaQuery()
                .eq(TicketOrderByScreeningDate::getSearchDate, searchDate)
                .count();
            if (count > 0) {
                log.info("C20数据已存在，searchDate: {}, 跳过处理", searchDate);
                return 0;
            }
        }

        List<TicketOrderByScreeningDate> orderList = new ArrayList<>();
        for (Map<String, String> record : records) {
            try {
                TicketOrderByScreeningDate order = new TicketOrderByScreeningDate();
                order.setCinemaId(cinemaId);
                //影院名称,影院编码,销售类型,销售时间,影票数,票价
                if (StringUtils.hasText(record.get("影院名称"))) {
                    order.setCinemaName(record.get("影院名称"));
                }
                if (StringUtils.hasText(record.get("影院编码"))) {
                    order.setCinemaCode(record.get("影院编码"));
                }
                if (StringUtils.hasText(record.get("销售类型"))) {
                    order.setSaleType(record.get("销售类型"));
                }
                // 处理销售时间
                String saleTimeStr = record.get("销售时间");
                if (StringUtils.hasText(saleTimeStr)) {
                    order.setSaleTime(LocalDateTime.parse(saleTimeStr, DATE_TIME_FORMATTER));
                }
                // 处理影票数
                String ticketCountStr = record.get("影票数");
                if (StringUtils.hasText(ticketCountStr)) {
                    order.setTicketCount(Integer.parseInt(ticketCountStr));
                }
                // 处理票价
                String ticketPriceStr = record.get("票价");
                if (StringUtils.hasText(ticketPriceStr)) {
                    order.setTicketPrice(new BigDecimal(ticketPriceStr));
                }
                // 服务费,网络代售费,支付金额,支付工具,支付工具编码
                String serviceFeeStr = record.get("服务费");
                if (StringUtils.hasText(serviceFeeStr)) {
                    order.setServiceFee(new BigDecimal(serviceFeeStr));
                }
                // 处理网络代售费
                String onlineSaleFeeStr = record.get("网络代售费");
                if (StringUtils.hasText(onlineSaleFeeStr)) {
                    order.setOnlineSaleFee(new BigDecimal(onlineSaleFeeStr));
                }
                // 处理支付金额
                String paymentAmountStr = record.get("支付金额");
                if (StringUtils.hasText(paymentAmountStr)) {
                    order.setPaymentAmount(new BigDecimal(paymentAmountStr));
                }
                if (StringUtils.hasText(record.get("支付工具"))) {
                    order.setPaymentTool(record.get("支付工具"));
                }
                if (StringUtils.hasText(record.get("支付工具编码"))) {
                    order.setPaymentToolCode(record.get("支付工具编码"));
                }
                // 最低票价,补贴方,优惠信息,优惠金额,第三方优惠信息,第三方优惠金额
                String minTicketPriceStr = record.get("最低票价");
                if (StringUtils.hasText(minTicketPriceStr)) {
                    order.setMinTicketPrice(new BigDecimal(minTicketPriceStr));
                }
                if (StringUtils.hasText(record.get("补贴方"))) {
                    order.setSubsidyParty(record.get("补贴方"));
                }
                if (StringUtils.hasText(record.get("优惠信息"))) {
                    order.setDiscountInfo(record.get("优惠信息"));
                }
                String discountAmountStr = record.get("优惠金额");
                if (StringUtils.hasText(discountAmountStr)) {
                    order.setDiscountAmount(new BigDecimal(discountAmountStr));
                }
                if (StringUtils.hasText(record.get("第三方优惠信息"))) {
                    order.setThirdPartyDiscountInfo(record.get("第三方优惠信息"));
                }
                String thirdPartyDiscountAmountStr = record.get("第三方优惠金额");
                if (StringUtils.hasText(thirdPartyDiscountAmountStr)) {
                    order.setThirdPartyDiscountAmount(new BigDecimal(thirdPartyDiscountAmountStr));
                }
                // 活动编码,活动名称,销售渠道,销售渠道编码,操作员,票号,影片名称,影厅名称,放映日期,放映时间
                if (StringUtils.hasText(record.get("活动编码"))) {
                    order.setActivityCode(record.get("活动编码"));
                }
                if (StringUtils.hasText(record.get("活动名称"))) {
                    order.setActivityName(record.get("活动名称"));
                }
                if (StringUtils.hasText(record.get("销售渠道"))) {
                    order.setSaleChannel(record.get("销售渠道"));
                }
                if (StringUtils.hasText(record.get("销售渠道编码"))) {
                    order.setSaleChannelCode(record.get("销售渠道编码"));
                }
                if (StringUtils.hasText(record.get("操作员"))) {
                    order.setTicketSeller(record.get("操作员"));
                }
                if (StringUtils.hasText(record.get("票号"))) {
                    order.setTicketNo(record.get("票号"));
                }
                if (StringUtils.hasText(record.get("影片名称"))) {
                    order.setMovieName(record.get("影片名称"));
                }
                if (StringUtils.hasText(record.get("影厅名称"))) {
                    order.setHallName(record.get("影厅名称"));
                }
                String screeningDateStr = record.get("放映日期");
                if (StringUtils.hasText(screeningDateStr)) {
                    order.setScreeningDate(LocalDate.parse(screeningDateStr, DATE_FORMATTER));
                }
                String screeningTimeStr = record.get("放映时间");
                if (StringUtils.hasText(screeningTimeStr)) {
                    order.setScreeningTime(LocalTime.parse(screeningTimeStr, TIME_FORMATTER));
                }
                // 座位号,票类,售订单号,退订单号,第三方订单号,影院所在区域,影票打印时间,支付使用券模版名称
                if (StringUtils.hasText(record.get("座位号"))) {
                    order.setSeatNo(record.get("座位号"));
                }
                if (StringUtils.hasText(record.get("票类"))) {
                    order.setTicketType(record.get("票类"));
                }
                if (StringUtils.hasText(record.get("售订单号"))) {
                    order.setSaleOrderNo(record.get("售订单号"));
                }
                if (StringUtils.hasText(record.get("退订单号"))) {
                    order.setRefundOrderNo(record.get("退订单号"));
                }
                if (StringUtils.hasText(record.get("第三方订单号"))) {
                    order.setThirdPartyOrderNo(record.get("第三方订单号"));
                }
                if (StringUtils.hasText(record.get("影院所在区域"))) {
                    order.setCinemaArea(record.get("影院所在区域"));
                }
                // 处理影票打印时间
                String ticketPrintTimeStr = record.get("影票打印时间");
                if (StringUtils.hasText(ticketPrintTimeStr)) {
                    order.setTicketPrintTime(LocalDateTime.parse(ticketPrintTimeStr, DATE_TIME_FORMATTER));
                }
                if (StringUtils.hasText(record.get("支付使用券模版名称"))) {
                    order.setPaymentCouponTemplateName(record.get("支付使用券模版名称"));
                }
                // 退票渠道编码,退票渠道名称,会员卡卡号,优惠券码,影票打印员工号,支付序列,影厅编码,影片编码
                if (StringUtils.hasText(record.get("退票渠道编码"))) {
                    order.setRefundChannelCode(record.get("退票渠道编码"));
                }
                if (StringUtils.hasText(record.get("退票渠道名称"))) {
                    order.setRefundChannelName(record.get("退票渠道名称"));
                }
                if (StringUtils.hasText(record.get("会员卡卡号"))) {
                    order.setMemberCardNo(record.get("会员卡卡号"));
                }
                if (StringUtils.hasText(record.get("优惠券码"))) {
                    order.setCouponCode(record.get("优惠券码"));
                }
                if (StringUtils.hasText(record.get("影票打印员工号"))) {
                    order.setTicketPrintEmployeeNo(record.get("影票打印员工号"));
                }
                if (StringUtils.hasText(record.get("支付序列"))) {
                    order.setPaymentSequence(record.get("支付序列"));
                }
                if (StringUtils.hasText(record.get("影厅编码"))) {
                    order.setHallCode(record.get("影厅编码"));
                }
                if (StringUtils.hasText(record.get("影片编码"))) {
                    order.setMovieCode(record.get("影片编码"));
                }
                // 券模版编码,支付使用卡名称,影城所属区域编码,销售员工号,取票员,会员ID,手机号,场次号
                if (StringUtils.hasText(record.get("券模版编码"))) {
                    order.setCouponTemplateCode(record.get("券模版编码"));
                }
                if (StringUtils.hasText(record.get("支付使用卡名称"))) {
                    order.setPaymentCardName(record.get("支付使用卡名称"));
                }
                if (StringUtils.hasText(record.get("影城所属区域编码"))) {
                    order.setCinemaAreaCode(record.get("影城所属区域编码"));
                }
                if (StringUtils.hasText(record.get("销售员工号"))) {
                    order.setSalesEmployeeNo(record.get("销售员工号"));
                }
                if (StringUtils.hasText(record.get("取票员"))) {
                    order.setTicketCollector(record.get("取票员"));
                }
                if (StringUtils.hasText(record.get("会员ID"))) {
                    order.setMemberId(record.get("会员ID"));
                }
                if (StringUtils.hasText(record.get("手机号"))) {
                    order.setMobilePhone(record.get("手机号"));
                }
                if (StringUtils.hasText(record.get("场次号"))) {
                    order.setScreeningNo(record.get("场次号"));
                }
                // 商户订单号,第三方支付流水号,影片国别,影片语言,影厅类型,其它费用
                if (StringUtils.hasText(record.get("商户订单号"))) {
                    order.setMerchantOrderNo(record.get("商户订单号"));
                }
                if (StringUtils.hasText(record.get("第三方支付流水号"))) {
                    order.setThirdPartyPaymentNo(record.get("第三方支付流水号"));
                }
                if (StringUtils.hasText(record.get("影片国别"))) {
                    order.setMovieCountry(record.get("影片国别"));
                }
                if (StringUtils.hasText(record.get("影片语言"))) {
                    order.setMovieLanguage(record.get("影片语言"));
                }
                if (StringUtils.hasText(record.get("影厅类型"))) {
                    order.setHallType(record.get("影厅类型"));
                }
                // 处理其它费用
                String otherFeesStr = record.get("其它费用");
                if (StringUtils.hasText(otherFeesStr)) {
                    order.setOtherFees(new BigDecimal(otherFeesStr));
                }

                // 处理新增字段
                if (StringUtils.hasText(record.get("活动类型"))) {
                    order.setActivityType(record.get("活动类型"));
                }
                String isTicketSubsidyStr = record.get("是否票补活动");
                if (StringUtils.hasText(isTicketSubsidyStr)) {
                    order.setIsTicketSubsidy("是".equals(isTicketSubsidyStr));
                }
                if (StringUtils.hasText(record.get("发卡影城编码"))) {
                    order.setCardIssuingCinemaCode(record.get("发卡影城编码"));
                }
                if (StringUtils.hasText(record.get("发卡影城名称"))) {
                    order.setCardIssuingCinemaName(record.get("发卡影城名称"));
                }
                if (StringUtils.hasText(record.get("发券影城编码"))) {
                    order.setCouponIssuingCinemaCode(record.get("发券影城编码"));
                }
                if (StringUtils.hasText(record.get("发券影城名称"))) {
                    order.setCouponIssuingCinemaName(record.get("发券影城名称"));
                }
                String refundFeeStr = record.get("退票手续费金额");
                if (StringUtils.hasText(refundFeeStr)) {
                    order.setRefundFee(new BigDecimal(refundFeeStr));
                }

                // 设置searchDate
                order.setSearchDate(searchDate);

                orderList.add(order);
            } catch (Exception e) {
                log.error("Error processing C20 record: {}", record, e);
                throw new RuntimeException("Failed to process C20 record", e);
            }
        }

        try {
            saveBatch(orderList);
            return orderList.size();
        } catch (Exception e) {
            log.error("Error saving C20 data batch", e);
            throw new RuntimeException("Failed to save C20 data batch", e);
        }
    }
}